package com.the8thfold.anton.ant

import org.apache.tools.ant.Project
import org.apache.tools.ant.ProjectHelper
import grails.plugins.springsecurity.Secured
import com.the8thfold.anton.utils.QuickId
import com.the8thfold.anton.users.User
import javax.swing.text.html.HTML
import grails.converters.JSON
import com.the8thfold.anton.settings.Configuration
import com.the8thfold.anton.utils.ConfigurationUtils
import com.the8thfold.anton.users.Roles

class ScriptController {

    def springSecurityService

    @Secured(['ROLE_SCRIPT_ADMIN'])
    def index = {
        redirect(action: "list", params: params)
    }

    @Secured(['ROLE_SCRIPT_ADMIN'])
    def list = {
        [scripts: AntScript.list()]
    }

    @Secured(['ROLE_SCRIPT_ADMIN'])
    def create = {

    }

    @Secured(['ROLE_SCRIPT_ADMIN'])
    def save = {
        if (params.id) {
            // Update
            AntScript script = AntScript.findByScriptId(params.id);
            script.description = params.scriptName;
            script.scriptFilePath = params.scriptPath;
            script.save(flush: true, failOnError: true)
        }
        else {
            // New
            AntScript script = new AntScript();
            script.scriptId = QuickId.newId;
            script.description = params.scriptName;
            def scriptFile = request.getFile("scriptFile");
            if (!scriptFile.empty) {
                File targetFile = new File(ConfigurationUtils.getScriptsFolderName(),script.scriptId);
                if (!targetFile.exists()) {targetFile.mkdirs()}
                File targetScriptFile = new File(targetFile,scriptFile.fileItem.fileName)
                scriptFile.transferTo(targetScriptFile)
                script.scriptFilePath = targetScriptFile.absolutePath;
                script.createdBy = User.get(springSecurityService.principal.id);

                script.save(flush: true, failOnError: true);
                redirect(action: 'list')
            }
            else {

            }
        }
    }

    @Secured(['ROLE_SCRIPT_ADMIN'])
    def edit = {

    }

    @Secured(['ROLE_SCRIPT_ADMIN'])
    def delete = {
        if (params.id){
            AntScript script = AntScript.findByScriptId(params.id);
            script.delete()
        }
        redirect(action: "list", params: params)
    }

    @Secured(['ROLE_SCRIPT_ADMIN'])
    def view = {
        def script = AntScript.findByScriptId(params.id)
        def contents = "Fail to read file"

        try {
            File buildFile = new File(script.scriptFilePath)
            if (buildFile.exists()) {

                contents = buildFile.text?.encodeAsHTML();

                Project antProject = new Project();
                antProject.setUserProperty("ant.file", buildFile.getAbsolutePath());
                ProjectHelper helper = ProjectHelper.getProjectHelper();
                antProject.init();
                antProject.addReference("ant.projectHelper", helper);
                helper.parse(antProject, buildFile);
                def props = System.properties
                def projectProperties = new Properties(antProject.properties)
                props.each {key, value ->
                    projectProperties.remove(key);
                }
                antProject.properties.each { key, value ->
                    if (key.startsWith("ant"))
                        projectProperties.remove(key);
                }
                projectProperties.sort {a, b ->
                    a.toString().compareTo(b.toString())
                }
                [script: script, antProject: antProject, projectProperties: projectProperties, contents: contents]
            }
            else {
                [script: script, error: "Failed to read ant project file. [${script.scriptFilePath}]"]
            }
        } catch (Exception e) {
            [script: script, error: e.getMessage(), contents: contents]
        };

    }


    /**
     * Generates JSON needed for a DataTables table.
     */
    @Secured(['ROLE_SCRIPT_ADMIN'])
    def dataTablesSource = {

        def propertiesToRender = ['description', 'path', 'createdBy', 'dateCreated', 'numOfJobs','action']

        def filters = []
        propertiesToRender.each { prop ->
            filters << "p.${prop} like :filter"
        }
        def filter = filters.join(" OR ")

        def dataToRender = [:]
        dataToRender.sEcho = params.sEcho
        dataToRender.aaData=[] // Array of products.

        dataToRender.iTotalRecords = AntScript.count()
        dataToRender.iTotalDisplayRecords = dataToRender.iTotalRecords

        /*def query = new StringBuilder("from Product as p where p.enabled=true")
        if ( params.sSearch ) {
            query.append(" and (${filter})")
        }
        query.append(" order by p.${propertiesToRender[params.iSortCol_0 as int]} ${params.sSortDir_0}")
        */
        def scripts = []
        /*if ( params.sSearch ) {
            // Revise the number of total display records after applying the filter
            def countQuery = new StringBuilder("select count(*) from Product as p where p.enabled=true")
            if ( params.sSearch ) {
                countQuery.append(" and (${filter})")
            }
            def result = Product.executeQuery(countQuery.toString(),
                    [filter: "%${params.sSearch}%"])
            if ( result ) {
                dataToRender.iTotalDisplayRecords = result[0]
            }
            products = Product.findAll(query.toString(),
                    [filter: "%${params.sSearch}%"],
                    [max: params.iDisplayLength as int, offset: params.iDisplayStart as int])
        } else {*/
        scripts = AntScript.findAll([max: params.iDisplayLength as int, offset: params.iDisplayStart as int])
        //}

        scripts?.each { script ->
            dataToRender.aaData << [script.description,
                    script.scriptFilePath,
                    script.createdBy.firstName + " " + script.createdBy.lastName,
                    script.dateCreated,
                    AntJob.findAllByScript(script).size(),
                    "<a href='a' class='ui-button'>aaa</a>"
            ]
        }

        render dataToRender as JSON
    }

    @Secured(['ROLE_SCRIPT_ADMIN'])
    def updateField = {
        if (params.id){
            AntScript script = AntScript.findByScriptId(params.id)
            script.properties.put(params.field, params.value)
            script.save(flush: true, failOnError: true)
        }
        render("")
    }
}
